/**
 * @file    app_main.c
 * @author  Azolla (1228449928@qq.com)
 * @brief   app mian func
 * @version 0.1
 * @date    2025-04-15
 *
 * @copyright Copyright (c) 2025
 * */
/******************************************************************************/
/* Inclue */
#include "debug.h"
 
#define TAG                  "app_main"
#define LOG_SET_LEVEL        LOG_LEVEL_INF
#include "hal_log.h"         /*!< Must be placed after LOG_SET_LEVEL >*/
void GPIO_Toggle_INIT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

#if CONFIG_FREERTOS
#include "FreeRTOSConfig.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
void vTaskFunction(void *pvParameters)
{
 
    while (1) {
        LOGI("vTaskFunction running...%s", (char *)pvParameters);
        vTaskDelay(3100 / portTICK_RATE_MS);
        LOGI("FreeHeapSize = %ld/%ld/%ld", (uint32_t)xPortGetMinimumEverFreeHeapSize(), (uint32_t)xPortGetFreeHeapSize(), (uint32_t)configTOTAL_HEAP_SIZE);
    }
}
 
void app_main_task(void *pvParameters)
{
    bool direct = true;
    int conut = 0;
    while (1) {
        GPIO_WriteBit(GPIOA, GPIO_Pin_0, direct); direct = !direct;
        vTaskDelay(1000 / portTICK_RATE_MS);
        LOGI("FreeRTOS conut = %d", conut++);
    }
}

#if configSUPPORT_STATIC_ALLOCATION
// 定义定时器任务的 TCB 和堆栈
static StaticTask_t xTimerTaskTCB;
static StackType_t  xTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
// 实现定时器任务内存分配回调函数
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
{
    *ppxTimerTaskTCBBuffer   = &xTimerTaskTCB;
    *ppxTimerTaskStackBuffer = xTimerTaskStack;
    *pulTimerTaskStackSize   = configTASK_STACK_SIZE(xTimerTaskStack);
}

// 定义空闲任务的 TCB 和堆栈
static StaticTask_t xIdleTaskTCB;
static StackType_t  xIdleTaskStack[ configMINIMAL_STACK_SIZE ];

// 实现 vApplicationGetIdleTaskMemory 函数
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{
    *ppxIdleTaskTCBBuffer   = &xIdleTaskTCB;
    *ppxIdleTaskStackBuffer = xIdleTaskStack;
    *pulIdleTaskStackSize   = configTASK_STACK_SIZE(xIdleTaskStack);
}
#endif
// 定义任务的 TCB 和堆栈
static StaticTask_t xTaskTCB;
static StackType_t  xTaskStack[ configMINIMAL_STACK_SIZE ];

static StaticTask_t xAppTaskTCB;
static StackType_t  xAppTaskStack[ configMINIMAL_STACK_SIZE ];

static StaticQueue_t xMutexBuffer;
SemaphoreHandle_t logMutex = NULL; // LOG互斥信号量句柄
static void task_init(void)
{
    logMutex = xQueueCreateMutexStatic(queueQUEUE_TYPE_MUTEX, &xMutexBuffer);

    LOGI("FreeRTOS Kernel Version: %s", tskKERNEL_VERSION_NUMBER);
    xTaskCreate(vTaskFunction, "Task1", configMINIMAL_STACK_SIZE, "1", 4, NULL);  // 8032

    LOGI("sizeof(xTaskStack) = %d", sizeof(xTaskStack));
     
    // 使用静态内存创建任务
    xTaskCreateStatic(
                app_main_task,       // 任务函数
                "app_main_task",     // 任务名称
                configTASK_STACK_SIZE(xTaskStack),  // 任务堆栈大小
                NULL,                // 任务参数
                tskIDLE_PRIORITY + 1,// 任务优先级
                xTaskStack,          // 任务堆栈
                &xTaskTCB );         // 任务TCB

    xTaskCreateStatic(
                app_main_task,       // 任务函数
                "app_main_task1",    // 任务名称
                configTASK_STACK_SIZE(xAppTaskStack),  // 任务堆栈大小
                NULL,                // 任务参数
                tskIDLE_PRIORITY + 2,// 任务优先级
                xAppTaskStack,          // 任务堆栈
                &xAppTaskTCB );         // 任务TCB

    vTaskStartScheduler();

    while(1);
} 
#endif

static void system_init(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    Delay_Init();
    USART_Printf_Init(115200);
    LOGI("SystemClk: %ldHz", SystemCoreClock);
    LOGI("ChipID: %08lx", DBGMCU_GetCHIPID() );
}

static void driver_init(void)
{
    GPIO_Toggle_INIT();
}
int main(void)
{
    system_init();

    driver_init();
 
#if CONFIG_FREERTOS
    task_init();
#endif

    while (1) {
        Delay_Ms(1000); 
        LOGI("Main loop running...");
    }
    return 0;
}
 